//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//

/// A template for writing tests.
///
/// To write tests, amend this module and define [facts] or [examples] (or both).
/// To run tests, evaluate the amended module.
@ModuleInfo { minPklVersion = "0.26.0" }
open module pkl.test

/// Named groups of boolean expressions that are expected to evaluate to [true].
///
/// If an expression evaluates to [false], it is reported as a test failure.
///
/// Example:
/// ```
/// // for brevity, code under test is defined here
/// function multiply(a, b) = a * b
///
/// facts {
///   ["multiply numbers"] {
///     multiply(3, 5) == 15
///     multiple(3, 0) == 1 // will be reported as a test failure
///   }
///   // more facts here
/// }
/// ```
facts: Mapping<String, Listing<Boolean>>?

/// Named groups of expressions whose results are expected to match results stored in _$filename-expected.pcf_.
///
/// If _$filename-expected.pcf_ does not exist, it is generated based on the examples' actual results.
/// After verifying the contents of this file, it should be added to version control.
///
/// If _$filename-expected.pcf_ does exist, its results are compared one-by-one to actual results.
/// If an actual result does not compare equal (according to `==`) to its expected result,
/// it is reported as a test failure, and _$filename-actual.pcf_ is generated to aid with debugging.
///
/// Example:
/// ```
/// // for brevity, code under test is defined here
/// local function createPigeon(_age) = new {
///   name = "Pigeon"
///   age = _age
/// }
///
/// examples {
///   ["create Pigeons"] {
///     createPigeon(21)
///     createPigeon(42)
///   }
///   // more examples here
/// }
/// ```
///
/// When the above code is evaluated for the first time, the following `$filename-expected.pcf` is generated:
/// ```
/// examples {
///   ["create Pigeons"] {
///     new {
///       name = "Pigeon"
///       age = 21
///     }
///     new {
///       name = "Pigeon"
///       age = 42
///     }
///   }
/// }
/// ```
///
/// To update expected results after making changes,
/// delete _$filename-expected.pcf_ and evaluate the test module again.
examples: Mapping<String, Listing<unknown>>?

/// Applies [fun] and returns the error thrown.
///
/// Throws if [fun] did not throw an error.
external const function catch(fun: () -> Any): String

/// Applies [fun] and returns the error thrown.
///
/// Returns [null] if [fun] did not throw an error.
external const function catchOrNull(fun: () -> Any): String?
